/**
 * 
 */
package upe.dsc.algorithms.swarm.pso.entities;

import java.util.Random;

import upe.dsc.algorithms.swarm.pso.process.PsoBasicImpl;
import upe.dsc.algorithms.swarm.pso.process.PsoInertiaImpl;

/**
 * @author danvalho
 * 
 */
public class GlobalParticle extends Particle {
	@Override
	protected void initialize(int dimensions) {
		super.initialize(dimensions);
	}

	public GlobalParticle(double[] position) {
		super(position);
	}

	public GlobalParticle(int dimensions) {
		super(dimensions);
	}

	@Override
	public void updatePosition(double c1, double c2) {
		Random random1 = new Random();
		Random random2 = new Random();
		double fi = c1 + c2;
		double k = 2 / Math.abs(2 - fi - Math.sqrt(Math.pow(fi, 2) - 4 * fi));
		// double random1 = RandomDouble.getRandomDouble(1.0, 5);
		// double random2 = RandomDouble.getRandomDouble(1.0, 5);
		for (int i = 0; i < this.position.length; i++) {
			switch (TYPE) {
			case BASIC:
				this.velocity[i] = this.velocity[i] + c1 * random1.nextDouble() * (this.pPosition[i] - this.position[i]) + c2 * random2.nextDouble()
						* (PsoBasicImpl.pGPosition[i] - this.position[i]);
				break;
			case INERTIA:
				this.velocity[i] = PsoInertiaImpl.inertiaFactor * this.velocity[i] + c1 * random1.nextDouble() * (this.pPosition[i] - this.position[i]) + c2
						* random2.nextDouble() * (PsoBasicImpl.pGPosition[i] - this.position[i]);
				break;
			case CONSTRICTED:
				this.velocity[i] = k
						* (this.velocity[i] + c1 * random1.nextDouble() * (this.pPosition[i] - this.position[i]) + c2 * random2.nextDouble()
								* (PsoBasicImpl.pGPosition[i] - this.position[i]));
			}
			// velocity limit
			if (this.velocity[i] > PsoBasicImpl.VELOCITY_MAX_VALUE) {
				this.velocity[i] = PsoBasicImpl.VELOCITY_MAX_VALUE;
			} else if (this.velocity[i] < PsoBasicImpl.VELOCITY_MIN_VALUE) {
				this.velocity[i] = PsoBasicImpl.VELOCITY_MIN_VALUE;
			}
			// update position value
			this.position[i] = this.position[i] + this.velocity[i];
			// search space limit
			if (this.position[i] > PsoBasicImpl.POSITION_MAX_VALUE) {
				this.position[i] = PsoBasicImpl.POSITION_MAX_VALUE;
				this.velocity[i] = this.velocity[i] * (-1);
			} else if (this.position[i] < PsoBasicImpl.POSITION_MIN_VALUE) {
				this.position[i] = PsoBasicImpl.POSITION_MIN_VALUE;
				this.velocity[i] = this.velocity[i] * (-1);
			}
		}
	}

}
